/**
 ***************************************(C) COPYRIGHT 2019 USTC**************************************
 * @file       bsp_uart.c
 * @brief      this file contains rc data receive and processing function
 * @note       
 * @Version    V1.0.0
 * @Date       
 ***************************************(C) COPYRIGHT 2019 USTC***************************************
 */
                                                                                                              
#include "string.h"
#include "stdlib.h"
#include "bsp_uart.h"
#include "usart.h"
#include "math.h"
#include "bsp_SPI.h"
#include "bsp_can.h"

uint8_t  dbus_buf[DBUS_MAX_LEN];
volatile RC_Ctl_t RC_DATA;

/**
  * @brief       handle received rc data
  * @param[out]  rc:   structure to save handled rc data
  * @param[in]   buff: the buff which saved raw rc data
  * @retval 
  */
void rc_callback_handler(uint8_t *buff)
{ 	
	RC_DATA.rc_ch0 = (buff[0] | buff[1] <<8) & 0x07FF;
  RC_DATA.rc_ch0 -= 1024;
  RC_DATA.rc_ch1 = (buff[1] >>3 | buff[2] *32) & 0x07FF;
  RC_DATA.rc_ch1 -= 1024;
  RC_DATA.rc_ch2 = (buff[2] /64 | buff[3] *4 | buff[4] *1024) & 0x07FF;
  RC_DATA.rc_ch2 -= 1024;
  RC_DATA.rc_ch3 = (buff[4] /2 | buff[5] *128) & 0x07FF;
	RC_DATA.rc_ch3 -= 1024;
	
  RC_DATA.rc_s1 = ((buff[5] >> 4) & 0x000C) >> 2;
  RC_DATA.rc_s2 = (buff[5] >> 4) & 0x0003;

	RC_DATA.mouse_x = ((int16_t)buff[6]) | ((int16_t)buff[7] << 8);
	RC_DATA.mouse_y = ((int16_t)buff[8]) | ((int16_t)buff[9] << 8);
	RC_DATA.mouse_z = ((int16_t)buff[10]) | ((int16_t)buff[11] << 8);
	RC_DATA.mouse_press_l = buff[12];
	RC_DATA.mouse_press_r = buff[13];
	RC_DATA.key_v = ((int16_t)buff[14]) | ((uint16_t)buff[15] << 8);
	RC_DATA.yaw=(((int16_t)buff[16] | ((int16_t)buff[17] << 8)) & 0x07FF)-1024;	
	
	if(RC_DATA.rc_ch0>660)	RC_DATA.rc_ch0=660;
	if(RC_DATA.rc_ch0<-660)	RC_DATA.rc_ch0=-660;
	if(RC_DATA.rc_ch1>660)	RC_DATA.rc_ch1=660;
	if(RC_DATA.rc_ch1<-660)	RC_DATA.rc_ch1=-660;
	if(RC_DATA.rc_ch2>660)	RC_DATA.rc_ch2=660;
	if(RC_DATA.rc_ch2<-660)	RC_DATA.rc_ch2=-660;
	if(RC_DATA.rc_ch3>660)	RC_DATA.rc_ch3=660;
	if(RC_DATA.rc_ch3<-660)	RC_DATA.rc_ch3=-660;
	if(RC_DATA.yaw>660)			RC_DATA.yaw=660;
	if(RC_DATA.yaw<-660)		RC_DATA.yaw=-660;
}

/**
  * @brief      callback this function when uart interrupt 
  * @param[in]  huart: uart IRQHandler id
  * @retval  
  */
void uart_receive_handler(UART_HandleTypeDef *huart)
{
	if (__HAL_UART_GET_FLAG(huart, UART_FLAG_IDLE) && 
			__HAL_UART_GET_IT_SOURCE(huart, UART_IT_IDLE))
	{
		/* clear idle it flag avoid idle interrupt all the time */
	__HAL_UART_CLEAR_IDLEFLAG(huart);
		
	/* handle received data in idle interrupt */
	if (huart == &DBUS_HUART)
	{
		volatile uint8_t x;
		/* handle dbus data dbus_buf from DMA */
		if ((uint8_t)(huart->pRxBuffPtr-dbus_buf) == DBUS_BUFLEN)
		{
			rc_callback_handler(dbus_buf);	
		}	
		huart->pRxBuffPtr=dbus_buf;
	}
		HAL_UART_Receive_IT(&DBUS_HUART,dbus_buf,DBUS_MAX_LEN);
	}
}

/**
  * @brief   initialize dbus uart device 
  * @param   
  * @retval  
  */
void dbus_uart_init(void)
{
	/* open uart idle it */
	__HAL_UART_CLEAR_IDLEFLAG(&DBUS_HUART);
	__HAL_UART_ENABLE_IT(&DBUS_HUART, UART_IT_IDLE|UART_IT_RXNE);
	HAL_UART_Receive_IT(&DBUS_HUART,dbus_buf,DBUS_MAX_LEN);
}
